/*
* Copyright (C) 2021 ~ 2022 Uniontech Technology Co., Ltd.
*
* Author:      zhangbingyi <zhangbingyi@uniontech.com>
*
* Maintainer:  zhangbingyi <zhangbingyi@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "usbrecordsdelegate.h"
#include "usbrecordsdatadefinition.h"

//#include <DFontSizeManager>
//#include <DApplicationHelper>

#include <QApplication>
#include <QMouseEvent>
#include <QPainter>
#include <QToolTip>

#define ICON_SPACE 10 // 左右两边的间隔

#define PIXELSIZE 2

USBRecordsDelegate::USBRecordsDelegate(QObject *parent)
    : QStyledItemDelegate(parent)
    , m_isLightTheme(true)
{
    // 判断系统主题色
//    m_isLightTheme = (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::ColorType::LightType);
//    connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::themeTypeChanged, this, [this](DGuiApplicationHelper::ColorType type) {
//        m_isLightTheme = (type == DGuiApplicationHelper::ColorType::LightType);
//    });
}

// 绘制
void USBRecordsDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyleOptionViewItem itemOption(option);
    if (index.row() % 2 == 1) {
//        DPalette pl(DApplicationHelper::instance()->palette(option.widget));
        QPalette pl = qApp->palette();
        QPainterPath path;
        if (index.column() == COLUMN_NAME) {
            path.setFillRule(Qt::WindingFill);
            path.addRoundedRect(option.rect, 10, 10); // 圆弧
            QRect temp_rect(option.rect.left() + 10, option.rect.top(), option.rect.width() - 10, option.rect.height()); // 编辑框大小
            path.addRect(temp_rect);
            painter->fillPath(path, pl.brush(QPalette::Background)); // 设置背景色
        } else if (index.column() == COLUMN_TIME || index.column() == COLUMN_STRATEGY) {
            painter->fillRect(option.rect, pl.brush(QPalette::Background));

        } else if (index.column() == COLUMN_OPERATION) {
            path.setFillRule(Qt::WindingFill);
            path.addRoundedRect(option.rect, 10, 10);
            QRect temp_rect(option.rect.left(), option.rect.top(), option.rect.width() / 2, option.rect.height());
            path.addRect(temp_rect);
            painter->fillPath(path, pl.brush(QPalette::Background));
        }
    }

    // 第1列 USB设备名称
    if (COLUMN_NAME == index.column()) {
        painter->save();
        QString usbName = index.model()->data(index, DATA_ROLE_NAME).toString();
        // 设置字体
//        int currentFontSize = DFontSizeManager::instance()->fontPixelSize(qApp->font());
        int currentFontSize = PIXELSIZE;
        QFont font;
        font.setPixelSize(currentFontSize);
        painter->setFont(font);
        QFontMetrics fontWidth(font);

        // 设置表格内容头部间隔
        //        itemOption.rect = option.rect.adjusted(10, 0, 0, 0);
        QRect textRect = itemOption.rect;
        QPoint textPoint(textRect.x() + 10, textRect.y() + 10);

        usbName = fontWidth.elidedText(usbName, Qt::ElideMiddle, itemOption.rect.width() - 10); // 设置缩略
        painter->drawText(textPoint, usbName); // 绘制文本
        painter->restore();
    }

    // 第2列 USB添加时间
    if (COLUMN_TIME == index.column()) {
        painter->save();
        QString usbAddTime = index.model()->data(index, DATA_ROLE_TIME).toString();
        // 设置字体
//        int currentFontSize = DFontSizeManager::instance()->fontPixelSize(qApp->font());
        int currentFontSize = PIXELSIZE;
        QFont font;
        font.setPixelSize(currentFontSize);
        QRect textRect = itemOption.rect;
        QPoint textPoint(textRect.x() + 10, textRect.y() + 10);
        painter->setFont(font);
        QFontMetrics fontWidth(font);
        usbAddTime = fontWidth.elidedText(usbAddTime, Qt::ElideMiddle, itemOption.rect.width() - 10); // 设置缩略
        painter->drawText(textPoint, usbAddTime); // 绘制文本
        painter->restore();
    }

    // 第3列 USB设置模式
    if (COLUMN_STRATEGY == index.column()) {
        painter->save();
        QString usbStrategy = index.model()->data(index, DATA_ROLE_STRATEGY).toString();
        // 设置字体
//        int currentFontSize = DFontSizeManager::instance()->fontPixelSize(qApp->font());
        int currentFontSize = PIXELSIZE;
        QFont font;
        font.setPixelSize(currentFontSize);
        QRect textRect = itemOption.rect;
        QPoint textPoint(textRect.x() + 10, textRect.y() + 10);
        painter->setFont(font);
        QFontMetrics fontWidth(font);

        usbStrategy = fontWidth.elidedText(usbStrategy, Qt::ElideMiddle, itemOption.rect.width() - 10); // 设置缩略
        painter->drawText(textPoint, usbStrategy); // 绘制文本
        painter->restore();
    }

    if (itemOption.state & QStyle::State_HasFocus) {
        itemOption.state = itemOption.state ^ QStyle::State_HasFocus;
    }

    // 第4列 USB操作
    if (COLUMN_OPERATION == index.column()) {
        painter->save();

        // 判断是否在白名单列表标志位
        QModelIndex tepIndex = index.model()->index(index.row(), COLUMN_DATA);
        bool isOnWhitelist = index.model()->data(tepIndex, DATA_ROLE_OP_STATUS).toBool();

        QRect rect = itemOption.rect;
        int spacing = (rect.width() - 2 * ICON_SIZE - ICON_SPACE) / 2 - 10;
        int heightSpacing = (rect.height() - ICON_SIZE) / 2;

        //根据主题绘制对应图标
        rect.setRect(rect.x() + ICON_SPACE, rect.y() + heightSpacing, ICON_SIZE, ICON_SIZE);
        painter->drawPixmap(rect, QIcon(":/icons/deepin/builtin/actions/icon_usbStorage_findDetails_16px.svg").pixmap(QSize(ICON_SIZE, ICON_SIZE)));
        QPixmap pix;
        if (!isOnWhitelist) {
            pix = QIcon(":/icons/deepin/builtin/actions/icon_addWhitelist_16px.svg").pixmap(QSize(ICON_SIZE, ICON_SIZE));
        } else {
            pix = QIcon(":/icons/deepin/builtin/actions/icon_removeWhitelist_16px.svg").pixmap(QSize(ICON_SIZE, ICON_SIZE));
        }
        rect.setRect(rect.x() + ICON_SIZE + spacing, rect.y(), ICON_SIZE, ICON_SIZE);
        painter->drawPixmap(rect, pix);
        painter->restore();
    }
    if (COLUMN_OPERATION != index.column()) QStyledItemDelegate::paint(painter, itemOption, index);
}

bool USBRecordsDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    QStyleOptionViewItem itemOption(option);
    if (index.column() == COLUMN_OPERATION) {
        // 处理鼠标点击事件
        QRect rect = itemOption.rect;
        QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
        m_mousePoint = mouseEvent->pos();
        int spacing = (rect.width() - ICON_SIZE * 2 - ICON_SPACE) / 2 - 10;
        int heightSpacing = (rect.height() - ICON_SIZE) / 2;
        m_viewDetails = QRect(rect.x() + ICON_SPACE, rect.y() + heightSpacing, ICON_SIZE, ICON_SIZE);
        m_addOrRemoveWhitelist = QRect(rect.x() + ICON_SPACE + ICON_SIZE + spacing, rect.y() + heightSpacing, ICON_SIZE, ICON_SIZE);

        QModelIndex operaIndex = index.model()->index(index.row(), COLUMN_DATA);
        bool isOnWhitelist = index.model()->data(operaIndex, DATA_ROLE_OP_STATUS).toBool();

        // 鼠标点击释放则触发信号
        if (event->type() == QEvent::MouseButtonRelease) {
            USBConnectionInfo info = getInfoFromIndex(index);
            if (m_viewDetails.contains(m_mousePoint)) {
                Q_EMIT sendShowUSBDetails(info);
            } else if (m_addOrRemoveWhitelist.contains(m_mousePoint)) {
                if (isOnWhitelist) {
                    Q_EMIT sendOperateWhitelist(USB_MANAGER_OP_TYPE_REMOVE, info);
                } else {
                    info.permMode = 0; // 添加时，设置默认读写权限
                    info.addedTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); // 添加时，时间替换最新时间
                    Q_EMIT sendOperateWhitelist(USB_MANAGER_OP_TYPE_ADD, info);
                }
            }
        }
    }
    return QStyledItemDelegate::editorEvent(event, model, option, index);
}

bool USBRecordsDelegate::helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    if (event->type() == QEvent::ToolTip) {
        QString tooltip;
        QStyleOptionViewItem itemOption(option);
        QRect rect = itemOption.rect;

        // 名称 第1列
        if (index.column() == COLUMN_NAME) {
            QRect usbNameRect(rect.x() + 10, rect.y() + 10, rect.width(), rect.height());
            // 判断是否缩略
            if (usbNameRect.contains(event->pos())) {
                tooltip = index.model()->index(index.row(), COLUMN_DATA).data(DATA_ROLE_NAME).toString();
            }
        }

        // 时间 第2列
        if (index.column() == COLUMN_TIME) {
            QRect usbTimeRect(rect.x() + 10, rect.y() + 10, rect.width(), rect.height());
            if (usbTimeRect.contains(event->pos())) {
                tooltip = index.model()->index(index.row(), COLUMN_DATA).data(DATA_ROLE_TIME).toString();
            }
        }

        // 限制状态 第3列
        if (index.column() == COLUMN_STRATEGY) {
            QRect usbTimeRect(rect.x() + 10, rect.y() + 10, rect.width(), rect.height());
            if (usbTimeRect.contains(event->pos())) {
                int strategy = index.model()->index(index.row(), COLUMN_DATA).data(DATA_ROLE_STRATEGY).toInt();
                //设置限制状态图标
                if (USB_PERM_MODE_RW == strategy) {
                    tooltip = (tr("Read-write")); // 读写
                } else if (USB_PERM_MODE_RO == strategy) {
                    tooltip = (tr("Read only")); // 只读
                } else {
                    tooltip = (tr("Block")); // 禁止
                }
            }
        }

        // 操作 第4列
        if (index.column() == COLUMN_OPERATION) {
            int detailPos = rect.left() + ICON_SPACE;
            int whitelistPos = detailPos + (rect.width() - ICON_SPACE) / 2 - 10;

            // 判断是否在白名单列表标志位
            QModelIndex tepIndex = index.model()->index(index.row(), COLUMN_DATA);
            bool isOnWhitelist = index.model()->data(tepIndex, DATA_ROLE_OP_STATUS).toBool();

            if (detailPos <= event->pos().x() && event->pos().x() <= detailPos + ICON_SIZE) {
                tooltip = QString(tr("Details"));
            } else if (whitelistPos <= event->pos().x() && event->pos().x() <= whitelistPos + ICON_SIZE) {
                isOnWhitelist ? tooltip = QString(tr("Remove from whitelist")) : tooltip = QString(tr("Add to whitelist"));
            }
        } else {
            QWidgetList qwl = QApplication::topLevelWidgets(); // 顶级小部件
            for (QWidget *qw : qwl) {
                if (QString("QTipLable") == qw->metaObject()->className()) {
                    qw->close();
                }
            }
        }

        QToolTip::showText(event->globalPos(), tooltip);
        return true;
    }

    return QStyledItemDelegate::helpEvent(event, view, option, index);
}

USBConnectionInfo USBRecordsDelegate::getInfoFromIndex(const QModelIndex &index) const
{
    USBConnectionInfo currentInfo;
    const QAbstractItemModel *model = index.model();
    currentInfo.name = model->index(index.row(), COLUMN_DATA).data(DATA_ROLE_NAME).toString();
    currentInfo.addedTime = model->index(index.row(), COLUMN_DATA).data(DATA_ROLE_TIME).toString();
    currentInfo.permMode = model->index(index.row(), COLUMN_DATA).data(DATA_ROLE_STRATEGY).toInt();
    currentInfo.serial = model->index(index.row(), COLUMN_DATA).data(DATA_ROLE_SERIAL).toString();
    currentInfo.vendorID = model->index(index.row(), COLUMN_DATA).data(DATA_ROLE_VENDOR_ID).toString();
    currentInfo.productID = model->index(index.row(), COLUMN_DATA).data(DATA_ROLE_PRODUCT_ID).toString();

    return currentInfo;
}
